<?php
/**
 * coreModelCacheDriverCommon
 *
 * 데이터 베이스 캐시 기반 클래스
 *
 * @package core
 * @author  Platform Team
 */

abstract class coreModelCacheDriverCommon
{
    /**
     * 유니크 아이디
     * @var string
     */
    protected $sUid;

    /**
     * 기본 만료 시간
     * @var int
     */
    protected $iExpireDef;

    /**
     * 캐시 사용 여부
     * @var boolean
     */
    protected $isUseCache;

    /**
     * 캐시 네임스페이스
     *
     * !!NOTICE!!
     * 기존에 setClass 메소드에서 캐시명을 받아들이는 부분때문에 이를 지원하기 위함.
     * 프레임워크 1.2 이후 버젼에서는 생성자에서 지정할 수 있도록 유도한다.
     *
     * @deprecated
     * @var string
     */
    private $sCacheNsp;

    /**
     * 생성자
     *
     * @param array $aConfig array(
     *  'Uid' => 유니크 아이디
     *  'CacheManage' => 캐시 드라이버 명
     *  'UseCache' => 캐시 사용 여부(boolean)
     *  'ExpireTime' => 기본 만료 시간(초단위)
     *  'DefaultPath' => 캐시 루트 경로
     *  'DirectoryVariance' => 캐시 디렉토리 분산 뎁스(기본 2 최대 3)
     *  'MemcacheHost' => 멤캐시 호스트 주소
     *  'MemcachePort' => 멤캐시 포트 주소
     * )
     */
    public function __construct($aConfig)
    {
        $this->isUseCache = ($aConfig['UseCache'] === true) ? true : false;
        $this->sUid = $aConfig['Uid'];
        $this->iExpireDef = (int)$aConfig['ExpireTime'];

        $this->open($aConfig);
    }

    /**
     * 캐시 드라이버 구동
     *
     * @param array $aConfig
     */
    abstract public function open($aConfig);

    /**
     * 캐시 드라이버 종료
     */
    abstract public function close();

    /**
     * 캐시 데이터 읽기
     *
     * @param string $sNsp
     * @param string $sKey
     * @return array(
     *  'identity' => 캐시 파일 경로 혹은 캐시 키(드라이버에 따라 다름)
     *  'itime' => 초기 생성 시간
     *  'expire' => 만료 시간
     *  'data' => 대상 데이터
     * ) | false
     */
    abstract public function read($sNsp, $sKey);

    /**
     * 캐시 데이터 생성
     *
     * @param string $sNsp
     * @param string $sKey
     * @param mixed $mValue
     * @return boolean
     */
    abstract public function write($sNsp, $sKey, $mValue, $iExpire);

    /**
     * 캐시 데이터 만료
     *
     * @param string $sNsp
     * @return boolean
     */
    abstract public function expire($sNsp);

    /**
     * 캐시 사용 여부 설정
     * 파라미터가 할당되지 않는 경우 현재 캐시 여부를 반환합니다.
     *
     * @param boolean $isEnabled
     * @return boolean
     */
    final public function useCache($isEnabled=null)
    {
        if ($isEnabled !== null) {
            $this->setUseCache($isEnabled);
        }

        return $this->isUseCache;
    }

    /**
     * 캐시용 데이터로 재가공
     *
     * @param mixed $mData
     * @param int $iExpire
     * @return array(
     *  'itime' => 최초 생성 시간
     *  'expire' => 만료 시간
     *  'data' => 대상 데이터
     * ) | false
     */
    final protected function generateData($mData, $iExpire)
    {
        if ($mData === false) return false;

        $aResult = array();

        $aResult['itime'] = time();
        $aResult['expire'] = $iExpire > 0 ? (int)$iExpire : $this->iExpireDef;
        $aResult['data'] = $mData;

        return $aResult;
    }

    /**
     * 캐시 데이터가 유효한지 검증
     *
     * @param array $aGenerateData
     * @return boolean
     */
    final protected function isValid($aGenerateData)
    {
        $iCurrTime = time();
        $iInitTime = $aGenerateData['itime'];
        $iExpire = $aGenerateData['expire'];

        $iCheck = $iCurrTime - $iInitTime;

        if ($iExpire > $iCheck) {
            return true;
        }

        return false;
    }

    /**
     * 캐시 네임스페이스 반환
     *
     * !!NOTICE!!
     * 프레임워크 1.2 이하 버젼에서 캐시 네임스페이스 영역을 setClass 메소드를 활용하는 부분때문에 생겨남.
     * 추후 제거될 예정
     *
     * @deprecated
     * @param string $sNsp
     * @return string
     */
    final protected function getNamespace($sNsp)
    {
        return !empty($this->sCacheNsp) ? $this->sCacheNsp : $sNsp;
    }

    /**
     * 제거될 예정의 메소드입니다.
     *
     * @deprecated
     */
    final public function setClass($mClass)
    {
        if (is_object($mClass)) {
            $this->sCacheNsp = get_class($mClass);
        } else {
            $this->sCacheNsp = $mClass;
        }

        return $this;
    }

    /**
     * 캐시 사용 여부 설정
     *
     * @deprecated
     */
    final public function setUseCache($isEnabled=false)
    {
        $this->isUseCache = ($isEnabled === true) ? true : false;

        return $this->isUseCache;
    }
}